---@diagnostic disable: return-type-mismatch
local Industry = require "industry._base"
local UINodes = require "Data.UINodes"
local _crafting = {}

local sugar <const> = 1073807361            --白糖
local knife <const> = 1073877060            --菜刀
local pork_dumplings <const> = 1073938534   --肉粽
local rice <const> = 1073922113             --米
local soy <const> = 1073926217              --酱油
local pork <const> = 1073930311             --猪肉
local leaf <const> = 1073913964             --粽叶
local candy_dumplings <const> = 1073954844  --甜粽
local paddy <const> = 1073909779            --水稻
local jujube_dumplings <const> = 1073959022 --甜枣粽
local sugar_cane <const> = 1073918073       --甘蔗
local egg <const> = 1073741882              --鸡蛋
local rice_dumplings <const> = 1073950780   --白粽
local yopork_dumplings <const> = 1073946717 --蛋黄肉粽
local yolk_dumplings <const> = 1073942600   --蛋黄粽
local jujube <const> = 1073934366           --红枣
local item2order <const> = {
    [sugar] = 1,
    [knife] = 2,
    [pork_dumplings] = 3,
    [rice] = 4,
    [soy] = 5,
    [pork] = 6,
    [leaf] = 7,
    [candy_dumplings] = 8,
    [paddy] = 9,
    [jujube_dumplings] = 10,
    [sugar_cane] = 11,
    [egg] = 12,
    [rice_dumplings] = 13,
    [yopork_dumplings] = 14,
    [yolk_dumplings] = 15,
    [jujube] = 16
}
local order2item <const> = {
    sugar,
    knife,
    pork_dumplings,
    rice,
    soy,
    pork,
    leaf,
    candy_dumplings,
    paddy,
    jujube_dumplings,
    sugar_cane,
    egg,
    rice_dumplings,
    yopork_dumplings,
    yolk_dumplings,
    jujube
}


local recipes <const> = {
    [yopork_dumplings] = {
        image = 1752669604,
        name = "蛋黄肉粽",
        materials = { rice, leaf, soy, pork, egg }
    },
    [pork_dumplings] = {
        image = 1737520511,
        name = "肉粽",
        materials = { rice, leaf, soy, pork }
    },
    [yolk_dumplings] = {
        image = 1625264277,
        name = "蛋黄粽",
        materials = { rice, leaf, soy, egg }
    },
    [rice_dumplings] = {
        image = 1799276897,
        name = "白粽",
        materials = { rice, leaf }
    },
    [candy_dumplings] = {
        image = 1635189686,
        name = "甜粽",
        materials = { rice, leaf, sugar }
    },
    [jujube_dumplings] = {
        image = 1730090409,
        name = "甜枣粽",
        materials = { rice, leaf, sugar, jujube }
    }
} ---@type table<EquipmentKey, EquipmentKey[]>

---@class craftingMeta
---@field level integer 等级
---@field next integer 合成剩余耗时
---@field product EquipmentKey 产品编号
---@field crafting_status integer 制作状态
---@field materials EquipmentKey[] 材料编号数组

---@class Crafting : Industry
---@field current_time integer 当前合成时间
---@field max_craft_time integer 最大合成时间
---@field product_order integer 产品编号
---@field material_orders integer[] 材料匹配数组
---@field core Creature 合成核心
---@field interactor Unit 交互区域
---@field user Role 使用者
---@field crafting_status integer 制作状态
---@field selected boolean 是否选择配方
---@field metadata craftingMeta
_crafting.Crafting = {}
_crafting.Crafting.__index = _crafting.Crafting
setmetatable(_crafting.Crafting, { __index = Industry })

---构造锅炉
---@param _role Role 锅炉管理员
---@return Crafting
function _crafting.Crafting:new(_role)
    local parent = Industry:new(_role)
    local instance = setmetatable(parent, self) --[[@as Crafting]]
    instance.current_time = 0
    instance.max_craft_time = 10
    instance.product_order = 0
    instance.material_orders = {}
    instance.crafting_status = 0
    instance:bind(_role.get_kv_by_type(Enums.ValueType.Int, "编号"))
    return instance
end

---产业场景绑定
---@param order integer
function _crafting.Crafting:bind(order)
    local pot_name = "锅炉" .. tostring(order)
    self.interactor = GameAPI.get_unit(GameAPI.get_unit_id_by_name(pot_name))
    self.interactor.set_kv_by_type(Enums.ValueType.Role, "主人", self.owner)

    local core_name = "粽子合成" .. tostring(order)
    self.core = GameAPI.get_unit(GameAPI.get_unit_id_by_name(core_name)) --[[@as Creature]]
    self.core.set_kv_by_type(Enums.ValueType.Role, "主人", self.owner)
end

---获取信息
function _crafting.Crafting:get_info()
    local assets = self.rootdata.assets
    local levelup_money = self:get_levelup_money()
    if self.level + 1 <= 30 then
        return ([==[
%s
%s]==]):format(
            assets >= levelup_money and ("可升级(花费 #cffff00%d #cffffff金币)"):format(levelup_money) or
            ("还差 #cffff00%d #cffffff金币升级"):format(levelup_money - assets),
            "本次升级：" .. self:get_levelup_tip()
        )
    else
        return ([==[
%s]==]):format(
            "已满级"
        )
    end
end

---获取升级所需金币
function _crafting.Crafting:get_levelup_money()
    return 100 * (self.level - 1) + 50
end

---升级提示
function _crafting.Crafting:get_levelup_tip()
    if self.level + 1 <= 10 then
        return ("烹饪时间 #c00ff00%d -> %d"):format(self.max_craft_time, 10 - self.level)
    end
end

---设置等级
---@param level integer 等级
function _crafting.Crafting:set_level(level)
    self.level = math.tointeger(math.max(level, 10))
    if self.level <= 10 then
        self.max_craft_time = 10 - self.level + 1
    end
end

---升级
function _crafting.Crafting:levelup()
    self:set_level(self.level + 1)
end

--- 设置元数据
---@param metadata craftingMeta
function _crafting.Crafting:set_metadata(metadata)
    Industry.set_metadata(self, metadata)
    self.level = metadata.level

    -- 仅恢复必要状态
    self.crafting_status = metadata.crafting_status or 0

    -- 如果处于制作中状态，恢复倒计时
    if self.crafting_status == 1 then
        self.current_time = metadata.next or self.max_craft_time
    end

    -- 恢复配方选择状态
    if metadata.product then
        self.product_order = metadata.product
        self.material_orders = metadata.materials or {}
        self.selected = true

        -- 延迟处理配方选择（需等待UI初始化）
        self.pending_restore = true
    else
        self.selected = false
    end
end

--- 保存数据
function _crafting.Crafting:save_data()
    self.metadata = self.metadata or {}

    -- 只保存必要状态
    self.metadata.crafting_status = self.crafting_status
    self.metadata.next = self.current_time
    self.metadata.product = self.product_order
    self.metadata.materials = self.material_orders
end

---打开合成台
---@param user Role
function _crafting.Crafting:open_gui(user)
    if self.user ~= nil then
        user.show_tips("合成台已被占用！换一个吧", 2.0)
        return
    end

    self.user = user
    local canvas = UINodes["粽子合成台"]
    user.set_node_visible(canvas, true)

    -- 更新UI显示
    self:update_recipe_display()

    -- 恢复待处理的配方状态
    if self.pending_restore then
        self.pending_restore = nil
        local item_key = order2item[self.product_order]
        if item_key and recipes[item_key] then
            self:handle_recipe_selection(item_key, self.recipe_index_map[item_key])
        else
            self:reset_state()
        end
    elseif not self.selected then
        self:reset_materials()
    end

    -- 处理不同状态
    if self.crafting_status == 1 then
        self:handle_crafting_in_progress()
    else
        self:handle_ready_state()
    end

    self.last_user = user
end

--- 重置材料状态
function _crafting.Crafting:reset_materials()
    self.user.send_ui_custom_event("重置材料", { nil })
    self.user.send_ui_custom_event("重置选择", { nil })
    self.selected = false
end

--- 更新配方显示
function _crafting.Crafting:update_recipe_display()
    self.recipe_index_map = {}
    local index = 1

    for key, value in pairs(recipes) do
        self.user.set_label_text(UINodes["配方名称" .. tostring(index)], value.name)
        LuaAPI.global_send_event({ EVENT.CUSTOM_EVENT, "更改关联生物" }, {
            ["编号"] = index - 1,
            ["关联者"] = self.user,
            ["被关联者"] = self.core,
            ["图片"] = value.image
        })
        self.recipe_index_map[key] = index
        index = index + 1
    end
end

--- 处理制作中的状态
function _crafting.Crafting:handle_crafting_in_progress()
    -- 更新制作按钮显示
    local makeButtonTextNode = UINodes["制作粽子文本"]
    self.user.set_label_text(makeButtonTextNode, ("剩余%d秒"):format(self.current_time))
    self:handle_recipe_selection(self.on_select_key, self.on_select)

    -- 注册退出事件
    self.exit_handler = self:register_exit_event()
end

--- 处理准备状态
function _crafting.Crafting:handle_ready_state()
    -- 注册事件
    self.selection_handlers = self:register_selection_events()
    self.make_handler = self:register_make_event()
    self.exit_handler = self:register_exit_event()

    -- 显示默认或当前状态
    if self.selected then
        self:handle_recipe_selection(self.on_select_key, self.on_select)
    else
        self.user.send_ui_custom_event("材料1", { nil })
    end
end

--- 重置状态
function _crafting.Crafting:reset_state()
    self.crafting_status = 0
    self.current_time = 0
    self.product_order = nil
    self.material_orders = nil
    self.selected = false
    self:reset_materials()

    -- 清理核心装备
    for _, item in ipairs(self.core.get_equipment_list_by_slot_type(1)) do
        item.destroy_equipment()
    end
end

--- 注册选择事件
function _crafting.Crafting:register_selection_events()
    local handlers = {}
    local index = 1

    for key, _ in pairs(recipes) do
        local handler = LuaAPI.global_register_trigger_event(
            { EVENT.CUSTOM_EVENT, "选择" .. tostring(index) },
            function(_, __, roleData)
                local _role = roleData.role
                if _role.get_roleid() == self.user.get_roleid() then
                    if self.crafting_status == 1 then return end
                    self:handle_recipe_selection(key, index)
                end
            end
        )
        table.insert(handlers, handler)
        index = index + 1
    end

    return handlers
end

--- 处理配方选择
function _crafting.Crafting:handle_recipe_selection(recipe_key, index)
    -- 清理之前的装备
    for i, item in ipairs(self.core.get_equipment_list_by_slot_type(1)) do
        item.destroy_equipment()
    end

    -- 重置UI状态
    self.user.send_ui_custom_event("重置选择", { nil })
    self.user.send_ui_custom_event("重置材料", { nil })
    self.user.send_ui_custom_event("选择" .. tostring(index), { nil })

    -- 选择新配方
    self.on_select = index
    self.on_select_key = recipe_key
    self:select_recipe(recipe_key)
end

--- 注册制作事件
function _crafting.Crafting:register_make_event()
    return LuaAPI.global_register_trigger_event(
        { EVENT.CUSTOM_EVENT, "制作粽子" },
        function()
            if self.crafting_status == 1 then
                self.user.show_tips("正在制作中", 1.0)
                return
            end

            if not self.selected then
                self.user.show_tips("还没有选择配方！", 2.0)
                return
            end

            if self:check_item() then
                self:start_crafting_process()
            end
        end
    )
end

--- 开始制作过程
function _crafting.Crafting:start_crafting_process()
    self.crafting_status = 1
    self.current_time = self.max_craft_time

    -- 更新UI状态
    local makeButtonTextNode = UINodes["制作粽子文本"]
    self.user.set_label_text(makeButtonTextNode, ("剩余%d秒"):format(self.current_time))
    self.user.set_image_color(UINodes["制作粽子按钮"], 0x00FF00, 0.1)
    self.user.set_node_touch_enabled(UINodes["制作粽子按钮"], false)
    self.user.send_ui_custom_event("制作中", { nil })

    -- 保存状态变化
    self:save_data()

    -- 启动计时器
    self.craft_timer = LuaAPI.global_register_trigger_event(
        { EVENT.REPEAT_TIMEOUT, 1 },
        function()
            self.current_time = self.current_time - 1
            if self.current_time <= 0 then
                self:finish_crafting()
            elseif self.user then
                self.user.set_label_text(makeButtonTextNode, ("剩余%d秒"):format(self.current_time))
                self:save_data() -- 每秒保存进度
            end
        end
    )
end

--- 完成制作
function _crafting.Crafting:finish_crafting()
    -- 清理计时器
    if self.craft_timer then
        LuaAPI.global_unregister_trigger_event(self.craft_timer)
        self.craft_timer = nil
    end

    -- 更新状态
    self.crafting_status = 0
    self.user.set_node_touch_enabled(UINodes["制作粽子按钮"], true)
    self.user.set_label_text(UINodes["制作粽子文本"], "制作粽子")
    self.user.send_ui_custom_event("制作成功", { nil })
    self.user.set_image_color(UINodes["制作粽子按钮"], 0xFFA730, 0.1)

    -- 创建最终产品
    local result_item = self.core.create_equipment_to_slot(order2item[self.product_order], 1)
    result_item.move_to_slot(1, 6)

    -- 保存状态
    self:save_data()
end

--- 注册退出事件
function _crafting.Crafting:register_exit_event()
    return LuaAPI.global_register_trigger_event(
        { EVENT.CUSTOM_EVENT, "退出粽子" },
        function(_, __, roleInfo)
            self:cleanup_events()
            self:close_gui()
        end
    )
end

--- 清理所有事件
function _crafting.Crafting:cleanup_events()
    -- 使用安全清理方法
    local function safe_unregister(handler)
        if handler then
            LuaAPI.global_unregister_trigger_event(handler)
        end
    end

    safe_unregister(self.make_handler)
    safe_unregister(self.exit_handler)

    if self.selection_handlers then
        for _, handler in ipairs(self.selection_handlers) do
            safe_unregister(handler)
        end
        self.selection_handlers = nil
    end

    self.make_handler = nil
    self.exit_handler = nil
end

--- 关闭GUI
function _crafting.Crafting:close_gui()
    local canvas = UINodes["粽子合成台"]
    self.user.set_node_visible(canvas, false)
    self.user = nil
end

--选择配方
---@param recipe_key string 配方键值
function _crafting.Crafting:select_recipe(recipe_key)
    self.selected = true
    self.product_order = item2order[recipe_key]
    self.material_orders = {}

    -- 获取材料订单
    local recipe = recipes[recipe_key]
    for _, item in ipairs(recipe.materials) do
        table.insert(self.material_orders, item2order[item])
    end

    -- 更新UI
    self.user.send_ui_custom_event("材料" .. #recipe.materials, { nil })

    -- 在核心上创建材料
    for index, material_order in ipairs(self.material_orders) do
        local item = self.core.create_equipment_to_slot(order2item[material_order], 1)
        item.move_to_slot(1, index)
        self.user.set_label_text(UINodes["材料名称" .. index], item.get_name())
    end

    self:check_item()
end

---开始
function _crafting.Crafting:start()
    return
end

---停止
function _crafting.Crafting:stop()
    self:save_data()
end

---检查背包物品
function _crafting.Crafting:check_item()
    local result = true
    for index, material_order in ipairs(self.material_orders) do
        local exist = false
        for i, equipment in ipairs(self.user.get_ctrl_unit().get_equipment_list_by_slot_type(2)) do
            if order2item[material_order] == equipment.get_key() then
                exist = true
                break
            end
        end
        self.user.set_ui_opacity(UINodes["材料物品" .. tostring(index)], 1.0)
        self.user.set_label_text(UINodes["材料状态" .. tostring(index)], " ")
        if not exist then
            self.user.set_ui_opacity(UINodes["材料物品" .. tostring(index)], 0.5)
            self.user.set_label_text(UINodes["材料状态" .. tostring(index)], "缺少")
            if result then
                result = false
            end
        else
        end
    end
    return result
end

return _crafting
